if not ElvUI or not ElvuiInfoLeft then return end

local db, cf, tukuilocal = unpack(ElvUI)

datatextPane = ElvuiInfoLeft

local dtsets = {
  recount = 7,
  cdur = 5,
  cbags = 6
}

--------------------------------------------------------------------
-- recount overlay
--------------------------------------------------------------------
local isHealer = false
local function checkHealer()
    if ((db.myclass == "PALADIN" and GetPrimaryTalentTree() == 1) or
        (db.myclass == "SHAMAN" and GetPrimaryTalentTree() == 3) or
        (db.myclass == "DRUID" and GetPrimaryTalentTree() == 3) or
        (db.myclass == "PRIEST" and GetPrimaryTalentTree() ~= 3))
    then
        isHealer = true
    end
end

local Recount = _G.Recount

if (dtsets.recount or 0) > 0 and (IsAddOnLoaded("Recount") or tdpsPlayer_) then
    local Stat = CreateFrame("Frame")
    Stat:EnableMouse(true)
    Stat:SetFrameStrata("BACKGROUND")
    Stat:SetFrameLevel(3)

    Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
    Stat:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
    Stat:RegisterEvent("PLAYER_TALENT_UPDATE")
    Stat:RegisterEvent("CHARACTER_POINTS_CHANGED")
    Stat:RegisterEvent("UNIT_INVENTORY_CHANGED")
    Stat:RegisterEvent("UPDATE_BONUS_ACTIONBAR")
    Stat:SetScript("OnEvent", checkHealer)
    checkHealer()

    local Text  = datatextPane:CreateFontString(nil, "OVERLAY")
    Text:SetFont(cf.media.font, cf.datatext.fontsize, "THINOUTLINE")
    db.PP(dtsets.recount, Text)

    local reportMode = "Current"      -- default report its current
    ---local reportMode = "Overall"     -- default report its overall

    --local DataTextFormat = "raid"     -- Show raid dps/healing
    local DataTextFormat = "personal"   -- Show my personal dps/healing
    --local DataTextFormat = "both"     -- Show my personal dps/healing and raid dps/healing

    function matchUnitGUID(unitname, guid)
        for _, data in pairs(Recount.db2.combatants) do
            if data.GuardianReverseGUIDs and data.GuardianReverseGUIDs[unitname] and data.GuardianReverseGUIDs[unitname].GUIDs then
                for k, v in pairs(data.GuardianReverseGUIDs[unitname].GUIDs) do
                    if v == guid then
                        return true
                    end
                end
            end
        end
        return false
    end

    Stat:SetScript("OnMouseDown", function(self, btn)
        if btn == "LeftButton" then
            GameTooltip:Hide()
            if Recount then
                if Recount.MainWindow:IsShown() then
                    Recount.MainWindow:Hide()
                else
                    Recount.MainWindow:Show()
                    Recount:RefreshMainWindow()
                end
            else -- tdps
                SlashCmdList.TINYDPS('') -- toggle
            end
        elseif btn == "MiddleButton" then
            GameTooltip:Hide()
            if DataTextFormat == "raid" then
                DataTextFormat = "personal"
            elseif DataTextFormat == "personal" then
                DataTextFormat = "both"
            elseif DataTextFormat == "both" then
                DataTextFormat = "raid"
            end
        elseif btn == "RightButton" then
            if reportMode == "Current" then
                reportMode = "Overall"
            else
                reportMode = "Current"
            end
            OnEnter(self)
        end
    end)

    local function FormatNum(value)
        if value < 100000 then
            return string.format("%.1f", value)
        elseif value < 1000000 then
            return string.format("%.2fk", value / 1000)
        else
            return string.format("%.2fm", value / 1000000)
        end
    end


    local int = 1
    local function Update(self, t)
        int = int - t
        if int < 0 then
            local dataMode
            if isHealer then
                dataMode = "Heal"
            else
                dataMode = "DPS"
            end

            local tableName
            if reportMode == "Overall" then
                tableName = "OverallData"
            elseif InCombatLockdown() then --Recount.InCombat then
                tableName = "CurrentFightData"
            else
                tableName = "LastFightData"
            end

            local rps, mydps, pos = getRaidValuePerSecond(self, tableName, dataMode)

            local txt
            if DataTextFormat ~= "raid" then
                txt = pos..":  "..FormatNum(mydps)
            else
                txt = ""
            end

            if DataTextFormat ~= "personal" then
                if DataTextFormat == "both" then
                    txt = txt.." "
                end
                txt = txt.."R: "..FormatNum(rps)
            end

            Text:SetText(txt)

            self:SetAllPoints(Text)
            int = 1
        end
    end

    Stat:SetScript("OnUpdate", Update)

    local ConvertDataSet = {
        ["OverallData"] = "Overall Data",
        ["CurrentFightData"] = "Current Fight",
        ["LastFightData"] = "Last Fight"
    }

    local tthead = {r = 0.4, g = 0.78, b = 1}
    local theal = {r = 0, g = 1, b = 0}
    local tdamage = {r = 1, g = 0, b = 0}
    local notgroup = {r = 0.35686274509804, g = 0.56470588235294, b = 0.031372549019608}
    local colortable = {}
    for class, color in pairs(_G["RAID_CLASS_COLORS"]) do
        colortable[class] = { r = color.r, g = color.g, b = color.b }
    end
    colortable["PET"] = {r = 0.09, g = 0.61, b = 0.55}
    colortable["UNKNOWN"] = {r = 0.49803921568627, g = 0.49803921568627, b = 0.49803921568627}
    colortable["MOB"] = {r = 0.58, g = 0.24, b = 0.63}
    colortable["UNGROUPED"] = {r = 0.63, g = 0.58, b = 0.24}
    colortable["HOSTILE"] = {r = 0.7, g = 0.1, b = 0.1}

    function getSumtable(self, tablename, mode)
        local data, fullname, totalsum, totalpersec, cursum, curpersec = nil, "", 0, 0, 0, 0


        local temptable = {}
        local sumtable = {}
        for _, data in pairs(Recount.db2.combatants) do
            if data.Fights and data.Fights[tablename] and (data.type == "Self" or data.type == "Grouped" or data.type == "Pet" or data.type == "Ungrouped") then
                if mode == "DPS" then
                    cursum, curpersec = Recount:MergedPetDamageDPS(data, tablename)
                elseif mode == "Heal" then
                    cursum, curpersec = Recount:MergedPetHealingDPS(data, tablename)
                end
                if data.type ~= "Pet" or (not Recount.db.profile.MergePets and data.Owner and (Recount.db2.combatants[data.Owner].type == "Self" or Recount.db2.combatants[data.Owner].type=="Grouped" or Recount.db2.combatants[data.Owner].type == "Ungrouped")) or (not Recount.db.profile.MergePets and data.Name and data.GUID and matchUnitGUID(data.Name, data.GUID)) then
                    if cursum > 0 then
                        totalsum = totalsum + cursum
                        --curpersec = math.floor(curpersec + 0.5)
                        totalpersec = totalpersec + curpersec
                        fullname = data.Name or _G["UNKNOWN"]
                        if data.type == "Pet" then
                            fullname = data.Name.." <"..data.Owner..">"
                        end
                        if mode == "DPS" then
                            temptable = {name = fullname, damage = cursum, dps = curpersec, enclass = data.enClass}
                        elseif mode == "Heal" then
                            temptable = {name = fullname, healing = cursum, hps = curpersec, enclass = data.enClass}
                        end
                        tinsert(sumtable, temptable)
                    end
                end
            end
        end
        if mode == "DPS" then
            table.sort(sumtable, function(a, b) return a.damage > b.damage end)
        elseif mode == "Heal" then
            table.sort(sumtable, function(a, b) return a.healing > b.healing end)
        end

        return sumtable, totalsum, totalpersec
    end

    local SumTable = {}

    function getRaidValuePerSecond(self, tablename, mode)
        local mydps, dps, curdps = 0, 0, 0
        local sum, mysum = 0, 0
        local n = 0
        for _, data in pairs(Recount.db2.combatants) do
            if data.Fights and data.Fights[tablename] and (data.type == "Self" or data.type == "Grouped" or data.type == "Pet" or data.type == "Ungrouped") then
                if mode == "DPS" then
                    sum, curdps = Recount:MergedPetDamageDPS(data, tablename)
                elseif mode == "Heal" then
                    sum, curdps = Recount:MergedPetHealingDPS(data, tablename)
                end
                if (data.type ~= "Pet")
                    or (not Recount.db.profile.MergePets
                        and data.Owner
                        and (Recount.db2.combatants[data.Owner].type == "Self"
                            or Recount.db2.combatants[data.Owner].type == "Grouped"
                            or Recount.db2.combatants[data.Owner].type == "Ungrouped"))
                    or (not Recount.db.profile.MergePets
                        and data.Name
                        and data.GUID
                        and matchUnitGUID(data.Name, data.GUID))
                then
                    dps = dps + curdps * 10
                    if (data.type == "Self") then
                        mydps = curdps * 10
                        mysum = sum
                    else
                        n = n + 1
                        SumTable[n] = sum
                    end
                end
            end
        end

        local pos = 1
        for i = 1, n do
            if mysum < SumTable[i] then
                pos = pos + 1
            end
        end

        return math.floor(dps + 0.5) / 10, math.floor(mydps + 0.5) / 10, pos
    end

    function DisplayTable(self, mode, repotType, amount)
        statsTable, totalsum, totalpersec = getSumtable(self, mode, repotType)

        if repotType == "DPS" then
            GameTooltip:AddDoubleLine("Damage Done", ConvertDataSet[mode], tdamage.r, tdamage.g, tdamage.b, tthead.r, tthead.g, tthead.b)
        elseif repotType == "Heal" then
            GameTooltip:AddDoubleLine("Healing Done", ConvertDataSet[mode],theal.r, theal.g, theal.b, tthead.r, tthead.g, tthead.b)
        end

        local numofcombatants = #statsTable

        if numofcombatants == 0 then
            GameTooltip:AddLine("No data to display")
        else
            if numofcombatants > amount then
                numofcombatants = amount
            end
            GameTooltip:AddDoubleLine("Total",format("%s (%s) 100.0%%", FormatNum(totalsum), FormatNum(totalpersec)))
            for i = 1, numofcombatants do
                if statsTable[i].enclass then
                    classc = colortable[statsTable[i].enclass]
                else
                    classc = notgroup
                end
                local persec, sum
                if repotType == "DPS" then
                    persec = statsTable[i].dps
                    sum = statsTable[i].damage
                else
                    persec = statsTable[i].hps
                    sum = statsTable[i].healing
                end
                GameTooltip:AddDoubleLine(format("%d. %s", i, statsTable[i].name), format("%s (%s) %.1f%%", FormatNum(sum), FormatNum(persec), 100*sum/totalsum), classc.r, classc.g, classc.b, classc.r, classc.g, classc.b)
            end
        end
    end

    function CreateTooltipData(self, amount)
        if reportMode == "Overall" then
            DisplayTable(self, "OverallData", "DPS", amount)

            GameTooltip:AddLine(" ")

            DisplayTable(self, "OverallData", "Heal",amount)
        else
            if Recount.InCombat then
                DisplayTable(self, "CurrentFightData", "DPS", amount)
            else
                DisplayTable(self, "LastFightData", "DPS", amount)
            end

            GameTooltip:AddLine(" ")

            if Recount.InCombat then
                DisplayTable(self, "CurrentFightData", "Heal", amount)
            else
                DisplayTable(self, "LastFightData", "Heal", amount)
            end
        end
    end

    function OnEnter(self)
        GameTooltip:SetOwner(self, "ANCHOR_BOTTOM", 0, db.Scale(6));
        GameTooltip:ClearAllPoints()
        --GameTooltip:SetPoint("BOTTOM", self, "TOP", 0, db.mult)
        GameTooltip:ClearLines()
        CreateTooltipData(self, 10)
        GameTooltip:Show()
    end

    Stat:SetScript("OnEnter", OnEnter)

    Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)

    Update(Stat, 10)
end

--------------------------------------------------------------------
-- COLORED DURABILITY
--------------------------------------------------------------------

if (dtsets.cdur or 0) > 0 then
	local Stat = CreateFrame("Frame")
	Stat:EnableMouse(true)
	Stat:SetFrameStrata("BACKGROUND")
	Stat:SetFrameLevel(3)

	local Text  = datatextPane:CreateFontString(nil, "OVERLAY")
	Text:SetFont(cf.media.font, cf.datatext.fontsize, "THINOUTLINE")
	db.PP(dtsets.cdur, Text)

    local function DurabilityColor(perc)
        if not perc or perc < 0 then return "|cFF555555" end
        if perc == 1 then
            return "|cFF005500" -- Dark green
        elseif perc >= .9 then
            return "|cFF00AA00" -- Green
        elseif perc > .5 then
            return "|cFFFFFF00" -- Yellow
        elseif perc > .2 then
            return "|cFFFF9900" -- Orange
        else
            return "|cFFFF0000" -- Red
        end
    end

	local Total = 0
	local current, max

	local function OnEvent(self)
		for i = 1, 11 do
			if GetInventoryItemLink("player", tukuilocal.Slots[i][1]) ~= nil then
				current, max = GetInventoryItemDurability(tukuilocal.Slots[i][1])
				if current then
					tukuilocal.Slots[i][3] = current/max
					Total = Total + 1
				end
			end
		end
		table.sort(tukuilocal.Slots, function(a, b) return a[3] < b[3] end)

		if Total > 0 then
			Text:SetText(DURABILITY..": "..DurabilityColor(tukuilocal.Slots[1][3])..floor(tukuilocal.Slots[1][3]*100).."%")
		else
			Text:SetText(DURABILITY..": 100%")
		end
		-- Setup Durability Tooltip
		self:SetAllPoints(Text)
		self:SetScript("OnEnter", function()
			if not InCombatLockdown() then
				GameTooltip:SetOwner(self, "ANCHOR_TOP", 0, db.Scale(6));
				GameTooltip:ClearAllPoints()
				GameTooltip:SetPoint("BOTTOM", self, "TOP", 0, db.mult)
				GameTooltip:ClearLines()
				for i = 1, 11 do
					if tukuilocal.Slots[i][3] ~= 1000 then
						green = tukuilocal.Slots[i][3]*2
						red = 1 - green
						GameTooltip:AddDoubleLine(tukuilocal.Slots[i][2], floor(tukuilocal.Slots[i][3]*100).."%",1 ,1 , 1, red + 1, green, 0)
					end
				end
				GameTooltip:Show()
			end
		end)
		self:SetScript("OnLeave", function() GameTooltip:Hide() end)
		Total = 0
	end

	Stat:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
	Stat:RegisterEvent("MERCHANT_SHOW")
	Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
	Stat:SetScript("OnMouseDown", function() ToggleCharacter("PaperDollFrame") end)
	Stat:SetScript("OnEvent", OnEvent)
end

--------------------------------------------------------------------
 -- COLORED BAGS
--------------------------------------------------------------------

if (dtsets.cbags or 0) > 0 then
	local Stat = CreateFrame("Frame")
	Stat:EnableMouse(true)
	Stat:SetFrameStrata("BACKGROUND")
	Stat:SetFrameLevel(3)

	local Text  = datatextPane:CreateFontString(nil, "OVERLAY")
	Text:SetFont(cf.media.font, cf.datatext.fontsize, "THINOUTLINE")
	db.PP(dtsets.cbags, Text)

	local function OnEvent(self, event, ...)
		local free, total,used = 0, 0, 0
        local color
		for i = 0, NUM_BAG_SLOTS do
			free, total = free + GetContainerNumFreeSlots(i), total + GetContainerNumSlots(i)
		end
        if free > (total / 2) then
          color = db.ValColor or valuecolor
        elseif free < (total / 3) then
          color = "|cffff0000"
        else
          color = "|cfffed100"
        end
		Text:SetText(tukuilocal.datatext_bags..color..free.."/"..total)
		self:SetAllPoints(Text)
	end

	Stat:RegisterEvent("PLAYER_LOGIN")
	Stat:RegisterEvent("BAG_UPDATE")
	Stat:SetScript("OnEvent", OnEvent)
	Stat:SetScript("OnMouseDown", function() OpenAllBags() end)
end

local bpn = CreateFrame("Frame", "ElvBottomFillerFrame", UIParent)
bpn:SetFrameLevel(1)
bpn:SetFrameStrata("BACKGROUND")
bpn:SetTemplate("Default", true)
--bpn:CreateShadow("Default")
bpn:ClearAllPoints()
bpn:SetWidth(UIParent:GetWidth() - cf.chat.chatwidth*2 - 24)
bpn:SetHeight(ElvuiInfoLeft:GetHeight())
bpn:SetPoint("BOTTOM", UIParent, "BOTTOM", 0, ElvuiInfoLeft:GetBottom())
--bpn.shadow:ClearAllPoints()
--bpn.shadow:SetPoint("TOPLEFT", bpn, "TOPLEFT", db.Scale(-4), db.Scale(4))
--bpn.shadow:SetPoint("BOTTOMRIGHT", bpn, "BOTTOMRIGHT", db.Scale(4), db.Scale(-4))
